Skip to content

fix(android): guard getLongVersionCode() for API < 28 to prevent launch crash#219

Merged
FeodorFitsner merged 3 commits into
mainfrom
fix/android-old-version-crash
Jun 29, 2026
Merged

fix(android): guard getLongVersionCode() for API < 28 to prevent launch crash#219
FeodorFitsner merged 3 commits into
mainfrom
fix/android-old-version-crash

Conversation

@FeodorFitsner

Copy link
Copy Markdown
Contributor

Problem

Flet/serious_python apps crash on launch on Android 8.1 and below (API < 28), while working on Android 9+ (API 28+). Reported in flet-dev/flet#6619 as a regression that started in Flet 0.81.0.

Root cause

AndroidPlugin.getAppVersion — which serious_python calls on every app startup (to build the site-packages cache-invalidation key, before Python starts) — calls PackageInfo.getLongVersionCode(), which is API 28+, unconditionally.

R8 (release builds) outlines API-28 calls into a synthetic class (AndroidPlugin$$ExternalSyntheticApiModelOutline0) and horizontally merges into it the API-28 outlines from other code — notably Flutter 3.41's new io.flutter.embedding.engine.image.ImageDecoderDefaultImpl (which uses android.graphics.ImageDecoder). Invoking the version-code outline on API < 28 forces that merged class to load/verify, and its references to android.graphics.ImageDecoder$OnHeaderDecodedListener (API 28) fail to resolve:

java.lang.NoClassDefFoundError: Failed resolution of: Landroid/graphics/ImageDecoder$OnHeaderDecodedListener;
  at com.flet.serious_python_android.AndroidPlugin.onMethodCall(...)
Caused by: java.lang.ClassNotFoundException: android.graphics.ImageDecoder$OnHeaderDecodedListener

→ uncaught on the platform-channel handler → app crash.

This explains the exact regression boundary: Flet 0.80.5 shipped Flutter 3.38.7 (no ImageDecoderDefaultImpl); Flet 0.81.0 bumped to Flutter 3.41.2, which added it. The unguarded getLongVersionCode() was always present but only became fatal once Flutter contributed an ImageDecoder outline for R8 to merge with.

Fix

Guard the call with Build.VERSION.SDK_INT and fall back to the deprecated versionCode int field on API < 28. The API-26 path then never invokes the outlined method, so the merged synthetic class is never loaded on old devices (it's only loaded lazily on first invocation).

Verification

Reproduced and verified on Android emulators with a stock flet create counter app (Flet 0.85.3 / Flutter 3.41.7, release APK):

Device Before After
Android 8.0 (API 26) ❌ crash on launch ✅ runs (counter renders, CPython loads)
Android 10 (API 29) ✅ runs ✅ runs

Deobfuscated the release mapping.txt to confirm the merged outline class contained both getLongVersionCode(PackageInfo) and the ImageDecoder methods.

Fixes flet-dev/flet#6619.

…ch crash

getAppVersion runs on every startup and called PackageInfo.getLongVersionCode()
(API 28+) unconditionally. R8 outlines the call into a synthetic class it may
merge with other API 28+ outlines (e.g. Flutter 3.41's ImageDecoder-based image
decoder); invoking that class on API < 28 fails verification with
NoClassDefFoundError (android.graphics.ImageDecoder$OnHeaderDecodedListener) and
crashes the app on launch on Android 8.1 and below.

Guard the call with Build.VERSION.SDK_INT and fall back to the deprecated
versionCode int field on older devices.
Update .fvmrc to use Flutter 3.44.4 (was 3.44.3). Ensures project uses the patched Flutter SDK version via FVM for consistency across environments.
@FeodorFitsner FeodorFitsner merged commit fd4cf7b into main Jun 29, 2026
1 of 50 checks passed
@FeodorFitsner FeodorFitsner deleted the fix/android-old-version-crash branch June 29, 2026 15:17
FeodorFitsner added a commit that referenced this pull request Jun 29, 2026
Lockstep version bump across all packages (pubspecs, darwin podspec,
android gradle) and CHANGELOG entries.

Contains the two Android fixes since v4.1.0:
* Guard getLongVersionCode() for API < 28 to prevent launch crash on
  Android 8.1 and below (#219).
* Bundle every ABI's _sysconfigdata into the ABI-common stdlib.zip,
  fixing a non-primary-ABI startup ModuleNotFoundError (#218).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Application crashes (only Android 8.1 and below and flet 0.81.0 and later)

1 participant